package com.dhcc.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.dhcc.api.R;
import com.dhcc.entity.*;
import com.dhcc.httpApiService.IdGeneratorService;
import com.dhcc.request.DeptPositionPutAssignRequest;
import com.dhcc.service.*;
import com.dhcc.support.Condition;
import com.dhcc.support.Query;
import com.dhcc.utils.AuthUtil;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户管理控制层接口
 *
 * @ProjectName Dhcc-Cloud
 * @PackageName com.dhcc.controller
 * @Title SysUserController
 * @Date 2024/11/19 下午5:52
 * @Author LiuGuoting
 */
@RestController
@RequestMapping("/sys/user")
public class SysUserController {

    /**
     * 用户表接口
     */
    @Resource
    private SysUserService sysUserService;
    /**
     * 部门表接口
     */
    @Resource
    private SysDeptService sysDeptService;
    /**
     * 岗位表接口
     */
    @Resource
    private SysPositionService sysPositionService;
    /**
     * 部门-岗位表接口
     */
    @Resource
    private SysDeptPositionService sysDeptPositionService;
    /**
     * 部门-岗位-用户表接口
     */
    @Resource
    private SysDeptPositionUserService sysDeptPositionUserService;
    /**
     * ID生成器接口
     */
    @Resource
    IdGeneratorService idGeneratorService;

    /**
     * 自定义分页 用户表
     *
     * @param subjectBasicInfo 用户信息
     * @param query            查询条件
     * @return 用户分页信息
     */
    @GetMapping("/page")
    public R<IPage<SysUser>> page(SysUser subjectBasicInfo, Query query) {
        IPage<SysUser> pages = sysUserService.selectUserPage(Condition.getPage(query), subjectBasicInfo);
        return R.data(pages);
    }

    /**
     * 获取所有用户列表（已启用状态，未删除的用户）
     *
     * @return 用户列表
     */
    @GetMapping("/list")
    public R<List<SysUser>> listAllUsers() {
        LambdaQueryWrapper<SysUser> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(SysUser::getStatus, 0);
        List<SysUser> users = sysUserService.list(queryWrapper);
        return R.data(users);
    }

    /**
     * 获取指定用户 ID 的用户信息
     *
     * @param id 用户ID
     * @return 用户信息
     */
    @GetMapping("/detail")
    public R<SysUser> getUserById(@RequestParam("id") Long id) {
        Optional<SysUser> user = Optional.ofNullable(sysUserService.getById(id));
        return user.map(R::data).orElseGet(() -> R.fail(401, "用户不存在"));
    }

    /**
     * 获取指定用户 ID 的部门岗位树
     *
     * @param id 用户ID
     * @return 用户信息
     */
    @GetMapping("/getDeptPositionTree")
    public R<List<Map<String, Object>>> getDeptPositionTree(@RequestParam("id") Long id) {
        // 创建部门与职位列表
        Map<String, List<String>> deptPositionsMap = new HashMap<>();
        // 根据用户ID获取部门岗位信息
        List<SysDeptPositionUser> deptPositionUsers = sysDeptPositionUserService.getIdsByUserId(String.valueOf(id));
        if (deptPositionUsers.isEmpty()) {
            return R.fail("该用户未分配部门岗位");
        }
        // 遍历用户的部门岗位信息
        for (SysDeptPositionUser deptPositionUser : deptPositionUsers) {
            // 获取部门-岗位关联表的ID
            Long departmentPosition = deptPositionUser.getDepartmentPosition();
            // 根据部门-岗位关联表的ID获取部门信息
            SysDeptPosition sysDeptPosition = sysDeptPositionService.getById(departmentPosition);

            if (sysDeptPosition != null) {
                // 获取部门ID
                Long departmentId = sysDeptPosition.getDepartmentId();
                // 获取岗位ID
                Long positionId = sysDeptPosition.getPositionId();

                // 根据部门ID和岗位ID获取部门和岗位信息
                SysDept sysDept = sysDeptService.getById(departmentId);
                SysPosition sysPosition = sysPositionService.getById(positionId);

                // 获取部门名称和岗位名称
                String deptName = sysDept.getDepartmentName();
                String positionName = sysPosition.getPositionName();

                // 如果部门已存在，则直接添加岗位
                if (deptPositionsMap.containsKey(deptName)) {
                    deptPositionsMap.get(deptName).add(positionName);
                } else {
                    // 如果部门不存在，则创建新条目
                    List<String> positionsList = new ArrayList<>();
                    positionsList.add(positionName);
                    deptPositionsMap.put(deptName, positionsList);
                }
            }
        }

        // 最终构建返回结果
        List<Map<String, Object>> deptAndPositionsList = new ArrayList<>();
        for (Map.Entry<String, List<String>> entry : deptPositionsMap.entrySet()) {
            Map<String, Object> deptAndPositions = new HashMap<>();
            deptAndPositions.put("deptName", entry.getKey());
            deptAndPositions.put("positionsName", entry.getValue());
            deptAndPositionsList.add(deptAndPositions);
        }

        return R.data(deptAndPositionsList);
    }


    /**
     * 新增用户信息
     *
     * @param sysUser 用户信息对象
     * @return 新增结果
     */
    @PostMapping("/add")
    public R<Boolean> addUser(@RequestBody SysUser sysUser) {
        // 调用服务层新增方法并包装结果
        Optional<Boolean> result = Optional.of(sysUserService.insertUser(sysUser));
        // 通过 Optional 判断新增是否成功
        return result
                // 如果值为 true，则表示新增成功
                .filter(Boolean::booleanValue)
                // 新增成功，返回成功响应
                .map(success -> R.data(true))
                // 新增失败时返回失败响应
                .orElseGet(() -> R.fail(401, "新增失败！"));

    }

    /**
     * 编辑用户信息
     *
     * @param sysUser
     * @return
     */
    @PostMapping("/update")
    public R<Boolean> updateUser(@RequestBody SysUser sysUser) {
        // 调用服务层更新方法并包装结果
        Optional<Boolean> result = Optional.of(sysUserService.updateUser(sysUser));
        // 通过 Optional 判断更新是否成功
        return result
                // 如果值为 true，则表示更新成功
                .filter(Boolean::booleanValue)
                // 更新成功，返回成功响应
                .map(success -> R.data(true))
                // 更新失败或用户不存在时返回失败响应
                .orElseGet(() -> R.fail(401, "更新失败或用户不存在"));
    }

    /**
     * 逻辑删除指定用户ID的用户信息
     *
     * @param params 用户ID
     * @return 删除结果
     */
    @PostMapping("/delete")
    public R<Boolean> deleteUser(@RequestBody Map<String, String> params) {
        // 从Map中获取id值，并转换为Long类型
        String id = params.get("id");
        // 调用服务层删除方法并包装结果
        Optional<Boolean> result = Optional.of(sysUserService.deleteByIdLogic(id));
        // 同时清理部门岗位用户表中的该用户的记录
        sysDeptPositionUserService.remove(Wrappers.lambdaQuery(SysDeptPositionUser.class)
                .eq(SysDeptPositionUser::getUserId, id));
        // 通过 Optional 判断删除是否成功
        return result
                // 如果值为 true，则表示删除成功
                .filter(Boolean::booleanValue)
                // 删除成功，返回成功响应
                .map(success -> R.data(true))
                // 删除失败或用户不存在时返回失败响应
                .orElseGet(() -> R.fail(401, "删除失败或用户不存在"));
    }

    /**
     * 逻辑删除批量用户ID的用户信息
     *
     * @param ids 用户ID集合
     * @return 删除结果
     */
    @PostMapping("/deleteBatch")
    public R<Boolean> deleteBatchUser(@RequestBody List<String> ids) {
        // 调用服务层删除方法并包装结果
        Optional<Boolean> result = Optional.of(sysUserService.deleteBatchByIdsLogic(ids));
        // 遍历用户ID集合
        for (String id : ids) {
            // 同时清理部门岗位用户表中的该用户的记录
            sysDeptPositionUserService.remove(Wrappers.lambdaQuery(SysDeptPositionUser.class)
                    .eq(SysDeptPositionUser::getUserId, id));
        }
        // 通过 Optional 判断删除是否成功
        return result
                // 如果值为 true，则表示删除成功
                .filter(Boolean::booleanValue)
                // 删除成功，返回成功响应
                .map(success -> R.data(true))
                // 删除失败或用户不存在时返回失败响应
                .orElseGet(() -> R.fail(401, "删除失败或用户不存在"));
    }

    /**
     * 更新用户状态
     *
     * @param sysUser
     * @return
     */
    @PostMapping("/updateStatus")
    public R<Boolean> updateStatus(@RequestBody SysUser sysUser) {
        // 调用服务层更新方法并包装结果
        Optional<Boolean> result = Optional.of(sysUserService.updateStatus(sysUser));
        // 通过 Optional 判断更新是否成功
        return result
                // 如果值为 true，则表示更新成功
                .filter(Boolean::booleanValue)
                // 更新成功，返回成功响应
                .map(success -> R.data(true))
                // 更新失败或用户不存在时返回失败响应
                .orElseGet(() -> R.fail(401, "更新失败或用户不存在"));
    }

    /**
     * 更新批量用户状态
     *
     * @param
     * @return
     */
    @PostMapping("/updateBatchStatus")
    public R<Boolean> updateBatchStatus(@RequestBody List<String> ids, int newStatus) {
        Optional<Boolean> result = Optional.of(sysUserService.updateBatchStatus(ids, newStatus));
        // 通过 Optional 判断更新是否成功
        return result
                // 如果值为 true，则表示更新成功
                .filter(Boolean::booleanValue)
                // 更新成功，返回成功响应
                .map(success -> R.data(true))
                // 更新失败或用户不存在时返回失败响应
                .orElseGet(() -> R.fail(401, "更新失败"));
    }


    /**
     * 获取部门-岗位树集合
     *
     * @return
     */
    @GetMapping("/getAssignTree")
    public R<List<Map<String, Object>>> getAssignTree() {
        // 获取所有部门和岗位数据
        // 查询所有部门
        Set<SysDept> departments = new HashSet<>(sysDeptService.list());
        // 查询所有岗位
        Set<SysPosition> positions = new HashSet<>(sysPositionService.list());
        // 查询部门岗位关系数据
        Set<SysDeptPosition> sysDeptPositionList = new HashSet<>(sysDeptPositionService.list());
        // 查询部门岗位关系数据
        List<Map<String, Object>> deptPositionTree = sysDeptPositionService.getDeptPositionTree(departments, positions, sysDeptPositionList);
        return R.data(deptPositionTree);
    }

    /**
     * 获取用户已分配的部门-岗位树集合
     *
     * @return
     */
    @GetMapping("/getAllowAssignTree")
    public R<List<Map<String, Object>>> getAllowAssignTree(@RequestParam("id") String id) {
        // 使用 Set 存储部门
        Set<SysDept> departments = new HashSet<>();
        // 使用 Set 存储岗位
        Set<SysPosition> positions = new HashSet<>();
        // 使用 Set 存储部门-岗位关系
        Set<SysDeptPosition> sysDeptPositionList = new HashSet<>();
        LambdaQueryWrapper<SysDeptPositionUser> sysDeptPositionUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysDeptPositionUserLambdaQueryWrapper.eq(SysDeptPositionUser::getUserId, id);
        List<SysDeptPositionUser> sysDeptPositionUsers = sysDeptPositionUserService.list(sysDeptPositionUserLambdaQueryWrapper);
        for (SysDeptPositionUser sysDeptPositionUser : sysDeptPositionUsers) {
            Long departmentPosition = sysDeptPositionUser.getDepartmentPosition();
            if (departmentPosition != null) {
                // 查询部门岗位关系数据
                SysDeptPosition sysDeptPosition = sysDeptPositionService.getById(departmentPosition);
                if (sysDeptPosition != null) {
                    Long departmentId = sysDeptPosition.getDepartmentId();
                    Long positionId = sysDeptPosition.getPositionId();

                    // 查询部门信息
                    SysDept sysDept = sysDeptService.getById(departmentId);
                    if (sysDept != null) {
                        // 添加当前部门
                        departments.add(sysDept);
                        // 递归添加所有父部门
                        addParentDepartments(sysDept, departments);
                    }

                    // 查询岗位信息
                    SysPosition sysPosition = sysPositionService.getById(positionId);
                    if (sysPosition != null) {
                        positions.add(sysPosition);
                    }

                    // 添加部门岗位关系
                    sysDeptPositionList.add(sysDeptPosition);
                }
            }

        }
        // 查询部门岗位关系数据
        List<Map<String, Object>> deptPositionTree = sysDeptPositionService.getDeptPositionTree(departments, positions, sysDeptPositionList);
        return R.data(deptPositionTree);
    }

    /**
     * 提交分配用户部门岗位
     *
     * @return R<Boolean>
     */
    @PostMapping("/putAssign")
    public R<Boolean> putAssign(@RequestBody List<DeptPositionPutAssignRequest> deptPositionPutAssignRequests) {
        // 获取当前登录用户ID
        String userId = AuthUtil.getUserId();
        // 创建一个空的SysDeptPositionUser用户-部门岗位关联表的关系列表
        List<SysDeptPositionUser> sysDeptPositionUserList = sysDeptPositionUserService.list();
        // 提取请求中的部门岗位关系
        for (DeptPositionPutAssignRequest deptPositionPutAssignRequest : deptPositionPutAssignRequests) {
            // 删除旧的用户-部门岗位关联表的关系
            LambdaQueryWrapper<SysDeptPositionUser> sysDeptPositionUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
            sysDeptPositionUserLambdaQueryWrapper.eq(SysDeptPositionUser::getUserId, Long.valueOf(userId));
            sysDeptPositionUserService.remove(sysDeptPositionUserLambdaQueryWrapper);
            // 获取部门ID
            String deptId = deptPositionPutAssignRequest.getDeptId();
            // 获取岗位ID集合
            List<String> positions = deptPositionPutAssignRequest.getPositionIds();
            for (String position : positions) {
                // 查询是否存在该部门岗位关系
                LambdaQueryWrapper<SysDeptPosition> sysDeptPositionLambdaQueryWrapper = new LambdaQueryWrapper<>();
                sysDeptPositionLambdaQueryWrapper.eq(SysDeptPosition::getDepartmentId, deptId);
                sysDeptPositionLambdaQueryWrapper.eq(SysDeptPosition::getPositionId, position);
                SysDeptPosition sysDeptPositionServiceOne = sysDeptPositionService.getOne(sysDeptPositionLambdaQueryWrapper);
                if (sysDeptPositionServiceOne == null) {
                    return R.fail(401, "部门岗位关系不存在!");
                }
                // 如果存在，则获取其ID
                Long sysDeptPositionServiceOneId = sysDeptPositionServiceOne.getId();
                // 构建用户部门岗位关系对象
                SysDeptPositionUser sysDeptPositionUser = new SysDeptPositionUser();
                sysDeptPositionUser.setId(idGeneratorService.nextId());
                sysDeptPositionUser.setDepartmentPosition(sysDeptPositionServiceOneId);
                sysDeptPositionUser.setUserId(Long.valueOf(userId));
                sysDeptPositionUserList.add(sysDeptPositionUser);
            }
        }
        // 保存用户部门岗位关系
        return R.status(sysDeptPositionUserService.saveOrUpdateBatch(sysDeptPositionUserList), "分配失败，请重试!");
    }

    /**
     * 递归添加父部门
     *
     * @param sysDept     当前部门
     * @param departments 部门集合
     */
    private void addParentDepartments(SysDept sysDept, Set<SysDept> departments) {
        if (sysDept.getFatherDepartmentId() != null) {
            // 查询父部门
            SysDept parentDept = sysDeptService.getById(sysDept.getFatherDepartmentId());
            if (parentDept != null) {
                // 添加父部门
                departments.add(parentDept);
                // 递归处理父部门的父部门
                addParentDepartments(parentDept, departments);
            }
        }
    }
}
